/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package modules.estoque.models.dao;

/**
 *
 * @author Clezio
 */
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import modules.estoque.exception.EspacoExcedidoPaleteException;
import modules.estoque.exception.EspacoExcedidoRuaException;
import modules.estoque.exception.ReincidenciaException;
import modules.estoque.models.dto.Entrada;
import modules.estoque.models.dto.Produto;
import modules.estoque.models.dto.Saida;
import modules.estoque.models.dto.custom.VwAgrupamentoProdutoPreco;
import modules.estoque.util.HibernateUtil;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;

public class EstoqueDAO extends AbstractDAO{

    private SessionFactory sessionFactory;

    public EstoqueDAO() throws Exception {
        sessionFactory = HibernateUtil.getSessionFactory();
    }

    public void registrarEntrada(Entrada entrada) throws Exception {
        Session session = sessionFactory.openSession();
        //Registrar entrada
        session.getTransaction().begin();
        session.merge(entrada);
//        session.flush();
        session.getTransaction().commit();
        session.close();
    }
    
    public void registrarSaida(Saida saida) throws Exception {
        Session session = sessionFactory.openSession();
        session.getTransaction().begin();
        session.save(saida);
        session.flush();
        session.getTransaction().commit();
        session.close();
    }

    public Entrada obterEntradaById(Integer id) {
        Session session = sessionFactory.openSession();
        Entrada entrada = (Entrada) session.load(Entrada.class, id);
        Entrada entradaDto = null;
        try {
            entradaDto = (Entrada) montarDtoRetorno(entrada);
        } catch (Exception ex) {
            Logger.getLogger(EstoqueDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
        session.flush();
        session.close();
        return entradaDto;
    }
    
    public Saida obterSaidaById(Integer id) {
        Session session = sessionFactory.openSession();
        Saida saida = (Saida) session.load(Saida.class, id);
        Saida entradaDto = null;
        try {
            entradaDto = (Saida) montarDtoRetorno(saida);
        } catch (Exception ex) {
            Logger.getLogger(EstoqueDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
        session.flush();
        session.close();
        return entradaDto;
    }

    public boolean estornarEntrada(Entrada entrada) throws ReincidenciaException{
        Session session = sessionFactory.openSession();
        session.getTransaction().begin();
        entrada = (Entrada) session.load(Entrada.class, entrada.getId());
        if(entrada.isCancelado()){
            session.close();
            throw new ReincidenciaException("Registro já estornado anteriormente");
        }
        entrada.setCancelado(true);
        session.update(entrada);
        session.flush();
        session.getTransaction().commit();
        session.close();
        return true;
    }
    
    public List<Entrada> listarEntradasByData(Date date) {
        Session session = sessionFactory.openSession();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        StringBuilder query = new StringBuilder("from Entrada ");
        query.append(" where data_entrada = '" + sdf.format(date) + "'");
        query.append(" order by id");
        Query result = session.createQuery(query.toString());
        List<Entrada> registrosTmp = result.list();
        List<Entrada> registros = new ArrayList(registrosTmp);
        session.flush();
        session.close();
        return registros;
    }
    
    public List<VwAgrupamentoProdutoPreco> listarEntradasAgrupadaByProdutoPreco(Produto produto) {
        Session session = sessionFactory.openSession();
        StringBuilder query = new StringBuilder("from VwAgrupamentoProdutoPreco ");
        query.append(" where produto_id = " + produto.getId());
//        query.append(" order by id");
        Query result = session.createQuery(query.toString());
        List<VwAgrupamentoProdutoPreco> registrosTmp = result.list();
        List<VwAgrupamentoProdutoPreco> registros = new ArrayList(registrosTmp);
        session.flush();
        session.close();
        return registros;
    }

    public List<Saida> listarSaidasByData(Date date) {
        Session session = sessionFactory.openSession();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        StringBuilder query = new StringBuilder("from Saida ");
        query.append(" where data_saida = '" + sdf.format(date) + "'");
        query.append(" order by id");
        Query result = session.createQuery(query.toString());
        List<Saida> registrosTmp = result.list();
        List<Saida> registros = new ArrayList(registrosTmp);
        session.flush();
        session.close();
        return registros;
    }
    
    public List<Entrada> listarEntradasByProduto(Produto produto) {
        Session session = sessionFactory.openSession();
        StringBuilder query = new StringBuilder("from Entrada ");
        query.append(" where cancelado = false produto_id = "+produto.getId());
        query.append(" order by data_entrada");
        Query result = session.createQuery(query.toString());
        List<Entrada> registrosTmp = result.list();
        List<Entrada> registros = new ArrayList(registrosTmp);
        session.flush();
        session.close();
        return registros;
    }

    public Saida obterSaidaById(int id) {
        Session session = sessionFactory.openSession();
        Saida saida = (Saida) session.load(Saida.class, id);
        Saida entradaDto = null;
        try {
            entradaDto = (Saida) montarDtoRetorno(saida);
        } catch (Exception ex) {
            Logger.getLogger(EstoqueDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
        session.flush();
        session.close();
        return entradaDto;
    }

    public boolean estornarSaida(Saida saida) throws ReincidenciaException,EspacoExcedidoPaleteException, EspacoExcedidoRuaException, Exception {
        Session session = sessionFactory.openSession();
        saida = (Saida) session.load(Saida.class, saida.getId());
        if(saida.isCancelado()){
            session.close();
            throw new ReincidenciaException("Registro já estornado anteriormente");
        }
        saida.setCancelado(true);
        session.update(saida);
        session.flush();
        session.close();
        return true;
    }
}
